package ValiEngine

import (
	"encoding/json"
	"sort"
)

type Rule interface {
	GetName() string
	GetKey() string
	GetDesc() string
	GetShow() bool
}

type WholeRule interface {
	GetName() string
	GetKey() string
	GetDesc() string
	GetShow() bool
	Vali(string) bool
}

type CalcRule interface {
	GetName() string
	GetKey() string
	GetDesc() string
	Vali(operator byte, operand1 int, operand2 int) bool
	GetShow() bool
}

type Rules []Rule

func (a Rules) Len() int { return len(a) }
func (s Rules) Less(i, j int) bool {
	aa := []byte(s[i].GetKey())
	bb := []byte(s[j].GetKey())
	bLen := len(bb)
	for idx, chr := range aa {
		if idx > bLen-1 {
			return false
		}
		if chr != bb[idx] {
			return chr < bb[idx]
		}
	}

	return true
}
func (a Rules) Swap(i, j int) { a[i], a[j] = a[j], a[i] }

var ruleMap map[string]Rule

func init() {
	ruleMap = make(map[string]Rule)
}

func RegisterRule(key string, rule Rule) {
	ruleMap[key] = rule
}

func GetAllRule() []Rule {
	var s Rules
	s = make(Rules, 0)
	for _, v := range ruleMap {
		// if v.GetShow() {
		s = append(s, v)
		// }
	}
	sort.Sort(s)
	return s
}

func GetCalcRulesByName(names []string) []CalcRule {
	s := make([]CalcRule, 0, len(ruleMap))
	for _, v := range ruleMap {
		if _, ok := v.(CalcRule); ok {
			for _, n := range names {
				if v.GetKey() == n {
					s = append(s, v.(CalcRule))
					break
				}
			}
		}

	}
	return s

}

func GetAllRuleJson() string {
	l := make([]map[string]string, 0)

	for _, v := range ruleMap {
		if v.GetShow() {
			m := make(map[string]string)
			m["name"] = v.GetName()
			m["key"] = v.GetKey()
			l = append(l, m)
		}
	}
	result, _ := json.Marshal(l)
	return string(result)
}
